
package com.bei_en.teacher.third.pay.web.alipay;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.httpclient.NameValuePair;
import com.bei_en.teacher.third.pay.controller.AlipayController;
import com.bei_en.teacher.third.pay.web.alipay.httpClient.HttpProtocolHandler;
import com.bei_en.teacher.third.pay.web.alipay.httpClient.HttpRequest;
import com.bei_en.teacher.third.pay.web.alipay.httpClient.HttpResponse;
import com.bei_en.teacher.third.pay.web.alipay.httpClient.HttpResultType;

/* *
 *类名：AlipaySubmit
 *功能：支付宝各接口请求提交类
 *详细：构造支付宝各接口表单HTML文本，获取远程HTTP数据
 *版本：3.3
 *日期：2012-08-13
 *说明：
 *以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
 *该代码仅供学习和研究支付宝接口使用，只是提供一个参考。
 */

public class AlipaySubmit {

    /**
     * 支付宝提供给商户的服务接入网关URL(新)
     */
    private static final String ALIPAY_GATEWAY_NEW = "https://mapi.alipay.com/gateway.do?";

    /**
     * 生成签名结果
     * @param sPara 要签名的数组
     * @return 签名结果字符串
     * @throws UnsupportedEncodingException 
     */
    public static String buildRequestMysign(Map<String, String> sPara)
	    throws UnsupportedEncodingException {

	String prestr = AlipayCore.createLinkString(sPara); // 把数组所有元素，按照“参数=参数值”的模式用“&”字符拼接成字符串
	String mysign = RSA.sign(prestr, AlipayController.my_private_key, "utf-8");
	return mysign;
    }

    /**
     * 生成要请求给支付宝的参数数组
     * @param sParaTemp 请求前的参数数组
     * @return 要请求的参数数组
     * @throws UnsupportedEncodingException 
     */
    public static Map<String, String> buildRequestPara(Map<String, String> sParaTemp)
	    throws UnsupportedEncodingException {

	// 除去数组中的空值和签名参数
	Map<String, String> sPara = AlipayCore.paraFilter(sParaTemp);
	// 生成签名结果
	String mysign = buildRequestMysign(sPara);

	// 签名结果与签名方式加入请求提交参数组中
//	sPara.put("sign", mysign);
//	sPara.put("sign_type", "RSA");

	return sPara;
    }

    /**
     * 建立请求，以表单HTML形式构造（默认）
     * @param sParaTemp 请求参数数组
     * @param strMethod 提交方式。两个值可选：post、get
     * @param strButtonName 确认按钮显示文字
     * @return 提交表单HTML文本
     * @throws UnsupportedEncodingException 
     */
    public static String buildRequest(Map<String, String> sParaTemp, String strMethod,
	    String strButtonName) throws UnsupportedEncodingException {

	// 待请求参数数组
	Map<String, String> sPara = buildRequestPara(sParaTemp);
	List<String> keys = new ArrayList<String>(sPara.keySet());

	StringBuffer sbHtml = new StringBuffer();

	sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\" action=\""
		+ALIPAY_GATEWAY_NEW+"_input_charset="+"utf-8"+"\" method=\""+strMethod+"\">");

	for (int i = 0; i<keys.size(); i++) {
	    String name = (String) keys.get(i);
	    String value = (String) sPara.get(name);

	    sbHtml.append("<input type=\"hidden\" name=\""+name+"\" value=\""+value+"\"/>");
	}

	// submit按钮控件请不要含有name属性
	sbHtml.append("<input type=\"submit\" value=\""+strButtonName
		+"\" style=\"display:none;\"></form>");
	sbHtml.append("<script>document.forms['alipaysubmit'].submit();</script>");

	return sbHtml.toString();
    }

    /**
     * 建立请求，以表单HTML形式构造，带文件上传功能
     * @param sParaTemp 请求参数数组
     * @param strMethod 提交方式。两个值可选：post、get
     * @param strButtonName 确认按钮显示文字
     * @param strParaFileName 文件上传的参数名
     * @return 提交表单HTML文本
     * @throws UnsupportedEncodingException 
     */
    public static String buildRequest(Map<String, String> sParaTemp, String strMethod,
	    String strButtonName, String strParaFileName) throws UnsupportedEncodingException {

	// 待请求参数数组
	Map<String, String> sPara = buildRequestPara(sParaTemp);
	List<String> keys = new ArrayList<String>(sPara.keySet());

	StringBuffer sbHtml = new StringBuffer();

	sbHtml.append("<form id=\"alipaysubmit\" name=\"alipaysubmit\"  enctype=\"multipart/form-data\" action=\""
		+ALIPAY_GATEWAY_NEW+"_input_charset="+"utf-8"+"\" method=\""+strMethod+"\">");

	for (int i = 0; i<keys.size(); i++) {
	    String name = (String) keys.get(i);
	    String value = (String) sPara.get(name);

	    sbHtml.append("<input type=\"hidden\" name=\""+name+"\" value=\""+value+"\"/>");
	}

	sbHtml.append("<input type=\"file\" name=\""+strParaFileName+"\" />");

	// submit按钮控件请不要含有name属性
	sbHtml.append("<input type=\"submit\" value=\""+strButtonName
		+"\" style=\"display:none;\"></form>");

	return sbHtml.toString();
    }

    /**
     * 建立请求，以模拟远程HTTP的POST请求方式构造并获取支付宝的处理结果
     * 如果接口中没有上传文件参数，那么strParaFileName与strFilePath设置为空值
     * 如：buildRequest("", "",sParaTemp)
     * @param strParaFileName 文件类型的参数名
     * @param strFilePath 文件路径
     * @param sParaTemp 请求参数数组
     * @return 支付宝处理结果
     * @throws Exception
     */
    public static String buildRequest(String strParaFileName, String strFilePath,
	    Map<String, String> sParaTemp) throws Exception {

	// 待请求参数数组
	Map<String, String> sPara = buildRequestPara(sParaTemp);

	HttpProtocolHandler httpProtocolHandler = HttpProtocolHandler.getInstance();

	HttpRequest request = new HttpRequest(HttpResultType.BYTES);
	// 设置编码集
	request.setCharset("utf-8");

	request.setParameters(generatNameValuePair(sPara));
	request.setUrl(ALIPAY_GATEWAY_NEW+"_input_charset="+"utf-8");

	HttpResponse response = httpProtocolHandler.execute(request, strParaFileName, strFilePath);
	if (response==null) {
	    return null;
	}

	String strResult = response.getStringResult();

	return strResult;
    }

    /**
     * MAP类型数组转换成NameValuePair类型
     * @param properties  MAP类型数组
     * @return NameValuePair类型数组
     */
    private static NameValuePair[] generatNameValuePair(Map<String, String> properties) {

	NameValuePair[] nameValuePair = new NameValuePair[properties.size()];
	int i = 0;
	for (Map.Entry<String, String> entry : properties.entrySet()) {
	    nameValuePair[i++] = new NameValuePair(entry.getKey(), entry.getValue());
	}

	return nameValuePair;
    }

    /**
     * 用于防钓鱼，调用接口query_timestamp来获取时间戳的处理函数
     * 注意：远程解析XML出错，与服务器是否支持SSL等配置有关
     * @return 时间戳字符串
     * @throws IOException
     * @throws DocumentException
     * @throws MalformedURLException
     */
    /*public static String query_timestamp() throws MalformedURLException,
                                                    DocumentException, IOException {

    //构造访问query_timestamp接口的URL串
    String strUrl = ALIPAY_GATEWAY_NEW + "service=query_timestamp&partner=" + AlipayConfig.partner + "&_input_charset" +"utf-8";
    StringBuffer result = new StringBuffer();

    SAXReader reader = new SAXReader();
    Document doc = reader.read(new URL(strUrl).openStream());

    List<Node> nodeList = doc.selectNodes("//alipay/*");

    for (Node node : nodeList) {
        // 截取部分不需要解析的信息
        if (node.getName().equals("is_success") && node.getText().equals("T")) {
            // 判断是否有成功标示
            List<Node> nodeList1 = doc.selectNodes("//response/timestamp/*");
            for (Node node1 : nodeList1) {
                result.append(node1.getText());
            }
        }
    }

    return result.toString();
    }*/
}
